﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using TccServicos.Util;

namespace TccServicos.Negocio
{
    public class Notificacao
    {
        public void SendNotification(string deviceToken, string notification, bool production = false)
        {
            TcpClient tcpClient = new TcpClient();

            try
            {
                var endereco = "gateway.sandbox.push.apple.com";
                var certificado = "BuscaPetDev.p12";
                var i = 0;
                foreach (var item in ConfigurationManager.AppSettings.AllKeys)
                {
                    if (production)
                    {
                        if (item == "NotificacaoEnderecoProduction")
                        {
                            endereco = ConfigurationManager.AppSettings[i];
                        }
                        else if (item == "CertificadoProduction")
                        {
                            certificado = ConfigurationManager.AppSettings[i];
                        }
                    }
                    else
                    {
                        if (item == "NotificacaoEndereco")
                        {
                            endereco = ConfigurationManager.AppSettings[i];
                        }
                        else if (item == "Certificado")
                        {
                            certificado = ConfigurationManager.AppSettings[i];
                        }
                    }
                    i++;
                    
                }

                string pasta = System.Web.HttpContext.Current.Server.MapPath("~/");

                int port = 2195;
                string hostname = endereco;
                //string hostname = "gateway.push.apple.com";
                string certificatePath = pasta + certificado;

                /*
                Log.GravarLog(string.Format("{0} Erro Path: {1}", "EnvioNotificacao", certificatePath));
                if (File.Exists(certificatePath))
                    Log.GravarLog(string.Format("{0} Erro Path: {1}", "EnvioNotificacao", "Existe o certificado"));
                */

                //X509Certificate2 clientCertificate = new X509Certificate2(File.ReadAllBytes(certificatePath), "Ljkrcertificado86");
                //X509Certificate2 clientCertificate = new X509Certificate2(certificatePath, "Ljkrcertificado86", X509KeyStorageFlags.MachineKeySet);
                X509Certificate2 clientCertificate = new X509Certificate2(File.ReadAllBytes(certificatePath), "Ljkrcertificado86", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
                X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);
                tcpClient = new TcpClient(hostname, port);
                SslStream sslStream = new SslStream(tcpClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);


                sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls12, false);
                MemoryStream memoryStream = new MemoryStream();
                BinaryWriter writer = new BinaryWriter(memoryStream);
                writer.Write((byte)0);
                writer.Write((byte)0);
                writer.Write((byte)32);
                writer.Write(HexStringToByteArray(deviceToken.ToUpper()));
                string payload = "{\"aps\":{\"alert\":\"" + notification + "\",\"badge\":1,\"sound\":\"default\"}}";
                writer.Write((byte)0);
                writer.Write((byte)payload.Length);
                byte[] payloadBytes = System.Text.Encoding.UTF8.GetBytes(payload);
                writer.Write(payloadBytes);
                writer.Flush();
                byte[] memoryStreamAsBytes = memoryStream.ToArray();
                sslStream.Write(memoryStreamAsBytes);
                sslStream.Flush();
                tcpClient.Close();
            }

            catch (Exception ex)
            {
                Log.GravarLog(string.Format("{0} Erro: {1}", "EnvioNotificacao", ex.ToString()));
            }
            finally
            {
                tcpClient.Close();
            }
        }

        private byte[] HexStringToByteArray(string hexString)
        {
            return Enumerable.Range(0, hexString.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToByte(hexString.Substring(x, 2), 16))
                     .ToArray();
        }

        private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            if (sslPolicyErrors == SslPolicyErrors.None) return true;
            return false;
        }
    }
}
